package com.test.updater.updatefsm;

import com.test.updater.fsm.FSMException;
import com.test.helper.DebugLogHelper;
import com.test.updater.fsm.FSMMachine;
import com.test.updater.fsm.FSMState;
import com.test.updater.fsm.Parameter;
import com.test.updater.versionupdater.Control;
import com.test.updater.versionupdater.OnEventListener;

import java.lang.ref.WeakReference;

/**
 * Created by lmy on 2015/8/13.
 */
public class State {

    public static class BaseState extends FSMState {
        public WeakReference<Control> mControl;

        public BaseState(int tag, FSMMachine fsmMachine, Control control) {
            super(tag, fsmMachine);
            mControl = new WeakReference<Control>(control);
        }

        @Override
        public void enter(Parameter parameter) throws FSMException {
        }

        @Override
        public void exit() {

        }
    }

    public static class NewState extends BaseState {
        public NewState(FSMMachine fsmMachine, Control control) {
            super(UpdateConfig.UPDATE_NEW_STATE_TAG, fsmMachine, control);
        }

        @Override
        public void enter(Parameter parameter) throws FSMException {
            DebugLogHelper.InfoPrint("NewState enter...");
        }

        @Override
        public void exit() {
            DebugLogHelper.InfoPrint("NewState exit...");
        }
    }

    public static class CheckWaitState extends BaseState {
        public CheckWaitState(FSMMachine fsmMachine, Control control) {
            super(UpdateConfig.UPDATE_CHECK_WAIT_STATE_TAG, fsmMachine, control);
        }

        @Override
        public void enter(Parameter parameter) throws FSMException {
            DebugLogHelper.InfoPrint("CheckWaitState enter...");

            UpdateParameter.CheckParameter p = (UpdateParameter.CheckParameter) parameter;

            //向control发送检测请求
            if (!mControl.get().checkUpdate(p.softId(), p.serviceId(), p.type(), p.ex0())) {
                p = null;

                //请求发送失败，转为finish状态
                mFsmMachine.get().dispatchEvent(Event.DownEvent.class, null);

                throw new UpdateException(OnEventListener.ERROR_CODE_CHECK_FAILURE,
                        OnEventListener.ERROR_MSG_CHECK_FAILURE);
            }
            p = null;
        }

        @Override
        public void exit() {
            DebugLogHelper.InfoPrint("CheckWaitState exit...");
        }
    }

    public static class CheckingState extends BaseState {

        public CheckingState(FSMMachine fsmMachine, Control control) {
            super(UpdateConfig.UPDATE_CHECKING_STATE_TAG, fsmMachine, control);
        }

        @Override
        public void enter(Parameter parameter) throws FSMException {
            DebugLogHelper.DebugLogPrint("CheckingState enter...", DebugLogHelper.DebugLogLevel.DEBUG_INFO);
        }

        @Override
        public void exit() {
            DebugLogHelper.InfoPrint("CheckingState exit...");
        }
    }

    public static class CheckedState extends BaseState {
        public CheckedState(FSMMachine fsmMachine, Control control) {
            super(UpdateConfig.UPDATE_CHECKED_STATE_TAG, fsmMachine, control);
        }

        @Override
        public void enter(Parameter parameter) throws FSMException {
            DebugLogHelper.InfoPrint("CheckedState enter...");
        }

        @Override
        public void exit() {
            DebugLogHelper.InfoPrint("CheckedState exit...");
        }
    }

    public static class CheckCancelingState extends BaseState {
        public CheckCancelingState(FSMMachine fsmMachine, Control control) {
            super(UpdateConfig.UPDATE_CHECK_CANCELING_TAG, fsmMachine, control);
        }

        @Override
        public void enter(Parameter parameter) throws FSMException {
            DebugLogHelper.InfoPrint("CheckCancelingState enter...");
            if (!mControl.get().cancelCheck()) {
                throw new UpdateException(OnEventListener.ERROR_CODE_CANCEL_FAILURE,
                        OnEventListener.ERROR_MSG_CANCEL_FAILURE);
            }
        }

        @Override
        public void exit() {
            DebugLogHelper.InfoPrint("CheckCancelingState exit...");
        }
    }

    public static class CheckCanceledState extends BaseState {
        public CheckCanceledState(FSMMachine fsmMachine, Control control) {
            super(UpdateConfig.UPDATE_CHECK_CANCELED_TAG, fsmMachine, control);
        }

        @Override
        public void enter(Parameter parameter) throws FSMException {
            DebugLogHelper.InfoPrint("CheckCanceledState enter...");
        }

        @Override
        public void exit() {
            DebugLogHelper.InfoPrint("CheckCanceledState exit...");
        }
    }

    public static class DownloadWaitState extends BaseState {
        public DownloadWaitState(FSMMachine fsmMachine, Control control) {
            super(UpdateConfig.UPDATE_DOWNLOAD_WAIT_STATE_TAG, fsmMachine, control);
        }

        @Override
        public void enter(Parameter parameter) throws FSMException {
            DebugLogHelper.InfoPrint("DownloadWaitState enter...");
            //向control发送下载请求
            UpdateParameter.DownloadParameter p = (UpdateParameter.DownloadParameter) parameter;
            if (!mControl.get().download(p.url(), p.filepath(), p.netType())) {
                p = null;
                //请求发送失败，转为finish状态
                mFsmMachine.get().dispatchEvent(Event.DownEvent.class, null);
                throw new UpdateException(OnEventListener.ERROR_CODE_DOWNLOAD_FAILURE,
                        OnEventListener.ERROR_MSG_DOWNLOAD_FAILURE);
                //mFsmMachine.get().dispatchEvent(Event.FinishEvent.class, null);
            }
            p = null;
        }

        @Override
        public void exit() {
            DebugLogHelper.InfoPrint("DownloadWaitState exit...");
        }
    }

    public static class DownloadingState extends BaseState {
        public DownloadingState(FSMMachine fsmMachine, Control control) {
            super(UpdateConfig.UPDATE_DOWNLOADING_STATE_TAG, fsmMachine, control);
        }

        @Override
        public void enter(Parameter parameter) throws FSMException {
            DebugLogHelper.InfoPrint("DownloadingState enter...");
        }

        @Override
        public void exit() {
            DebugLogHelper.InfoPrint("DownloadingState exit...");
        }
    }

    public static class DownloadCancelingState extends BaseState {
        public DownloadCancelingState(FSMMachine fsmMachine, Control control) {
            super(UpdateConfig.UPDATE_DOWNLOAD_CANCELING_TAG, fsmMachine, control);
        }

        @Override
        public void enter(Parameter parameter) throws FSMException {
            DebugLogHelper.InfoPrint("DownloadCancelingState enter...");
            if (!mControl.get().cancelDownload()) {
                //mFsmMachine.get().dispatchEvent(Event.FinishEvent.class, null);
                throw new UpdateException(OnEventListener.ERROR_CODE_CANCEL_FAILURE,
                        OnEventListener.ERROR_MSG_CANCEL_FAILURE);
            }
        }

        @Override
        public void exit() {
            DebugLogHelper.InfoPrint("DownloadCancelingState exit...");
        }
    }

    public static class DownloadCanceledState extends BaseState {
        public DownloadCanceledState(FSMMachine fsmMachine, Control control) {
            super(UpdateConfig.UPDATE_DOWNLOAD_CANCELED_TAG, fsmMachine, control);
        }

        @Override
        public void enter(Parameter parameter) throws FSMException {
            DebugLogHelper.InfoPrint("DownloadCanceledState enter...");
            //调用finishDownload
            mControl.get().finishDownload();
            //下载结束就退出状态机，不能退出
            //mFsmMachine.get().dispatchEvent(Event.FinishEvent.class, null);
        }

        @Override
        public void exit() {
            DebugLogHelper.InfoPrint("DownloadCanceledState exit...");
        }
    }

    public static class DownloadedState extends BaseState {
        public DownloadedState(FSMMachine fsmMachine, Control control) {
            super(UpdateConfig.UPDATE_DOWNLOADED_STATE_TAG, fsmMachine, control);
        }

        @Override
        public void enter(Parameter parameter) throws FSMException {
            DebugLogHelper.DebugLogPrint("DownloadedState enter...",
                    DebugLogHelper.DebugLogLevel.DEBUG_INFO);

            //调用finishDownload
            mControl.get().finishDownload();
            //下载结束就退出状态机
            // mFsmMachine.get().dispatchEvent(Event.FinishEvent.class, null);
        }

        @Override
        public void exit() {
            DebugLogHelper.InfoPrint("DownloadedState exit...");
        }
    }

    public static class FinishState extends BaseState {
        public FinishState(FSMMachine fsmMachine, Control control) {
            super(UpdateConfig.UPDATE_FINISH_STATE_TAG, fsmMachine, control);
        }

        @Override
        public void enter(Parameter parameter) throws FSMException {
            DebugLogHelper.InfoPrint("FinishState enter...");
            //先不关闭，只是一种状态
            //mFsmMachine.get().endFsmProcess();
        }

        @Override
        public void exit() {
            DebugLogHelper.InfoPrint("FinishState exit...");
        }
    }
}
